package es.uc3m.tutorial.components.general;

import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGroup;

import org.ajax4jsf.component.html.HtmlAjaxSupport;
import org.richfaces.component.html.HtmlColumn;
import org.richfaces.component.html.HtmlDataTable;
import org.richfaces.component.html.HtmlDatascroller;
import org.richfaces.component.html.HtmlScrollableDataTable;
import org.richfaces.component.html.HtmlSpacer;
import org.richfaces.component.html.HtmlToolTip;
import org.richfaces.model.Ordering;

import es.uc3m.dei.fw2008.FacesUtils;
import es.uc3m.dei.fw2008.ui.components.DEIComponent;

public class SigameDataTable  extends DEIComponent {
	
	public final static String SCROLL_CONTROLS_TOP = "SC_TOP";	
	public final static String SCROLL_CONTROLS_BOTTOM = "SC_BOTTOM";	
	public final static String SCROLL_CONTROLS_BOTH = "SC_BOTH";
	
	public final static String SORT_ASDENDING = "ASCENDING";
	public final static String SORT_DESDENDING = "DESCENDING";
	
	private String id;
	
	private String title;
	
	private String dataBeanName;
	
	private String dataBeanProperty;
	
	private String actionBeanRowClickMethod;
	
	private String actionBeanRowDblClickMethod;
	
	private List<String> dataBeanItems; 
	
	private List<String> headerLabels;
	
	private List<String> columnsWidth;
	
	private String rowsBeanProperty;
	
	private String scrollControlsPosition;
	
	private String reRender;
	
	private String rowsTitle;
	
	private List<Boolean> dataAsCellTitle;
	
	private List<Boolean> sortable;
	
	private int inititalSortColumnId;
	
	private String initialSortType;	
	
	
	public SigameDataTable() {
		super();
		id = "sgm_table" + (int)(Math.random() * 1000000000);
		title = null;
		dataBeanName = null;
		dataBeanProperty = null;
		actionBeanRowClickMethod = null;
		actionBeanRowDblClickMethod = null;
		dataBeanItems = null;		
		headerLabels = null;
		columnsWidth = null;
		rowsBeanProperty = null;
		reRender = null;
		scrollControlsPosition = SCROLL_CONTROLS_BOTTOM;
		rowsTitle = null;
		dataAsCellTitle = null;
		sortable = null;
		inititalSortColumnId = 0;
		initialSortType = SORT_DESDENDING;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDataBeanName() {
		return dataBeanName;
	}

	public void setDataBeanName(String dataBeanName) {
		this.dataBeanName = dataBeanName;
	}

	public String getDataBeanProperty() {
		return dataBeanProperty;
	}

	public void setDataBeanProperty(String dataBeanProperty) {
		this.dataBeanProperty = dataBeanProperty;
	}

	public List<String> getDataBeanItems() {
		return dataBeanItems;
	}

	public void setDataBeanItems(List<String> dataBeanItems) {
		this.dataBeanItems = dataBeanItems;
	}

	public List<String> getHeaderLabels() {
		return headerLabels;
	}

	public void setHeaderLabels(List<String> headerLabels) {
		this.headerLabels = headerLabels;
	}

	public List<String> getColumnsWidth() {
		return columnsWidth;
	}

	public void setColumnsWidth(List<String> columnsWidth) {
		this.columnsWidth = columnsWidth;
	}

	public String getActionBeanRowClickMethod() {
		return actionBeanRowClickMethod;
	}

	public void setActionBeanRowClickMethod(String actionBeanRowClickMethod) {
		this.actionBeanRowClickMethod = actionBeanRowClickMethod;
	}

	public String getActionBeanRowDblClickMethod() {
		return actionBeanRowDblClickMethod;
	}

	public void setActionBeanRowDblClickMethod(String actionBeanRowDblClickMethod) {
		this.actionBeanRowDblClickMethod = actionBeanRowDblClickMethod;
	}

	public String getRowsBeanProperty() {
		return rowsBeanProperty;
	}

	public void setRowsBeanProperty(String rowsBeanProperty) {
		this.rowsBeanProperty = rowsBeanProperty;
	}

	public String getScrollControlsPosition() {
		return scrollControlsPosition;
	}

	public void setScrollControlsPosition(String scrollControlsPosition) {
		this.scrollControlsPosition = scrollControlsPosition;
	}

	public String getReRender() {
		return reRender;
	}

	public void setReRender(String reRender) {
		this.reRender = reRender;
	}

	public String getRowsTitle() {
		return rowsTitle;
	}

	public void setRowsTitle(String rowsTitle) {
		this.rowsTitle = rowsTitle;
	}	

	public void setDataAsCellTitle(List<Boolean> dataAsCellTitle) {
		this.dataAsCellTitle = dataAsCellTitle;
	}
	
	public void setSortable(List<Boolean> sortable) {
		this.sortable = sortable;
	}
	
	public void setInitialSortColumnId(int id) {
		this.inititalSortColumnId = id;
	}

	public void setInitialSortType(String initialSortType) {
		this.initialSortType = initialSortType;
	}

	@Override
	public UIComponent paint() {
								
		HtmlPanelGroup main = new HtmlPanelGroup();
		HtmlDataTable table = new HtmlDataTable();
		table.setId(id);
		table.setStyleClass("sgm-datatable");
		
		String auxScript =
			"<script type=\"text/javascript\">" +
			"\n "+id+"_selcol=null;" +
			"\n function "+id+"rowClick(row){" +
			"\n   if("+id+"_selcol!=null){" +
			"\n     "+id+"_selcol.style.backgroundColor='#{a4jSkin.tableBackgroundColor}';" +
			"\n   }" +
			"\n   row.style.backgroundColor='#B0C4DE';" +
			"\n   "+id+"_selcol=row;" +
			"\n }" +
			"\n function "+id+"rowClickByControl(element){" +
			"\n   "+id+"rowClick(element.parentNode);" +
			"\n }" +
			"\n function "+id+"rowMouseOver(row){" +
			"\n   if("+id+"_selcol==null || row!="+id+"_selcol){" +
			"\n     row.style.backgroundColor='#F1F1F1';" +
			"\n   }";			
		if (rowsTitle != null) {
			auxScript = auxScript +
			"\n   row.title='"+rowsTitle+"';";	
		}	
		auxScript = auxScript +
			"\n }" +
			"\n function "+id+"rowMouseOut(row){" +
			"\n   if("+id+"_selcol==null || row!="+id+"_selcol){" +
			"\n     row.style.backgroundColor='#{a4jSkin.tableBackgroundColor}';" +
			"\n   }" +			
			"\n }" +
			"\n</script>";
		
		HtmlOutputText auxjs = new HtmlOutputText();
		auxjs.setEscape(false);		
		auxjs.setValueExpression("value", FacesUtils.createValueExpression(auxScript, String.class));
								
		table.setStyle("width:100%;");
		table.setRowKeyVar("rkv");				
        table.setSortMode(HtmlScrollableDataTable.SORT_SINGLE);           
		table.setVar("item");		
		
		if (this.title != null) {
			HtmlOutputText title = new HtmlOutputText();
			title.setValue(this.title);
			table.getFacets().put("header", title);
		}
		
		if (dataBeanName != null) {
			if (dataBeanProperty != null)
				table.setValueExpression("value", FacesUtils.createValueExpression("#{"+dataBeanName+"."+dataBeanProperty+"}", List.class));
			if (rowsBeanProperty != null)
				table.setValueExpression("rows", FacesUtils.createValueExpression("#{"+dataBeanName+"."+rowsBeanProperty+"}", Integer.class));
			if (actionBeanRowClickMethod != null) {
				HtmlAjaxSupport rwCl = new HtmlAjaxSupport();			
				rwCl.setId(id+"_ca");				
				rwCl.setEvent("onRowClick");		
				rwCl.setOnsubmit("showGlobalMessage('"+FacesUtils.getMessageResourceString("messageAccessInfo")+"');");
				rwCl.setLimitToList(true);				
				rwCl.setActionExpression(FacesUtils.createMethodExpression("#{"+dataBeanName+"."+actionBeanRowClickMethod+"}", void.class, new Class<?>[0]));
				rwCl.setOncomplete(id+"rowClickByControl(this);hideGlobalMessage();");
				if (reRender != null)
					rwCl.setReRender(reRender);
				table.getChildren().add(rwCl);
			} else {
				table.setOnRowClick(id+"rowClick(this);"); // TODO
			}
			if (actionBeanRowDblClickMethod != null) {
				HtmlAjaxSupport rwDCl = new HtmlAjaxSupport();
				rwDCl.setId(id+"_dca");
				rwDCl.setEvent("onRowDblClick");
				rwDCl.setDisableDefault(false);
				rwDCl.setActionExpression(FacesUtils.createMethodExpression("#{"+dataBeanName+"."+actionBeanRowDblClickMethod+"}", void.class, new Class<?>[0]));
				if (reRender != null)
					rwDCl.setReRender(reRender);
				table.getChildren().add(rwDCl);
			}
		}			
		
		table.setOnRowMouseOver(id+"rowMouseOver(this);");
        table.setOnRowMouseOut(id+"rowMouseOut(this);"); 						
		
		int i = 0;
		for (String item : dataBeanItems){
					
			HtmlColumn col = new HtmlColumn();			
			col.setId(id+"_col"+i);												
			col.setStyle("cursor:default;");					
			
			try {			
				col.setWidth(columnsWidth.get(i));
			} catch (Exception e){
				col.setWidth("100px");
			}
			
			HtmlOutputText header = new HtmlOutputText();
			try {
				header.setValue(headerLabels.get(i));				  				
			} catch (Exception e){
				header.setValue("");
			}
			col.getFacets().put("header", header);
			header.setParent(col);
						
			HtmlOutputText data = new HtmlOutputText();			
			
			data.setValueExpression("value", FacesUtils.createValueExpression("#{item."+item+"}", String.class));
			
			col.getChildren().add(data);			
			
			if (rowsTitle == null && dataAsCellTitle != null && dataAsCellTitle.size()-1 > i && dataAsCellTitle.get(i)) {				
				HtmlToolTip tooltip = new HtmlToolTip();
				tooltip.setShowDelay(500);
				tooltip.setHideDelay(100);
				tooltip.setValueExpression("value", FacesUtils.createValueExpression("#{item."+item+"}", String.class));				
				
				col.getChildren().add(tooltip);				
			}
			
			if (sortable != null && sortable.get(i)) {								
				col.setSortable(true);
				col.setValueExpression("sortBy", FacesUtils.createValueExpression("#{item."+item+"}", String.class));
				if (i == inititalSortColumnId) {
					if (initialSortType.equals(SORT_ASDENDING))
						col.setSortOrder(Ordering.ASCENDING);
					else 
						col.setSortOrder(Ordering.DESCENDING);
				}				
			} else { 
				col.setSortable(false);
			}			
			
			table.getChildren().add(col);			
			i++;
		}					
		
		main.getChildren().add(auxjs);						
		
		HtmlDatascroller scrollerTop = null;
		HtmlDatascroller scrollerBottom = null;
				
		if (scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_TOP) || 
			scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_BOTH)) {
			scrollerTop = new HtmlDatascroller();
			scrollerTop.setId(id + "_scltop");		
		}
		
		if (scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_BOTTOM) || 
			scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_BOTH)) {
			scrollerBottom = new HtmlDatascroller();
			scrollerBottom.setId(id + "_sclbottom");
		}
		
		
		if (scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_TOP) || 
			scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_BOTH)) {
			scrollerTop.setFor(id);
			String reRenderCode = id + "," + scrollerTop.getId();
			if (scrollerBottom != null)
				reRenderCode = reRenderCode + "," + scrollerBottom.getId();
			scrollerTop.setReRender(reRenderCode);			
			scrollerTop.setLimitToList(true);
			HtmlSpacer sp1 = new HtmlSpacer();
			sp1.setHeight("4px");
			main.getChildren().add(scrollerTop);			
			main.getChildren().add(sp1);
		}
		
		main.getChildren().add(table);		
		
		if (scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_BOTTOM) || 
			scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_BOTH)) {
			scrollerBottom.setFor(id);
			String reRenderCode = id + "," + scrollerBottom.getId();
			if (scrollerTop != null)
				reRenderCode = reRenderCode + "," + scrollerTop.getId();
			scrollerBottom.setReRender(reRenderCode);
			scrollerBottom.setLimitToList(true);
			HtmlSpacer sp2 = new HtmlSpacer();
			sp2.setHeight("4px");
			main.getChildren().add(sp2);
			main.getChildren().add(scrollerBottom);			
		}
		
		if (scrollControlsPosition.equalsIgnoreCase(SCROLL_CONTROLS_BOTH)) {
			scrollerTop.setReRender(scrollerBottom.getId());
			scrollerBottom.setReRender(scrollerTop.getId());
		}
		
		return main;	
	}
	
	@Override
	public void add(DEIComponent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void remove(DEIComponent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public DEIComponent getChild(int arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	
}
